home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume6 / xnetld / patch1 next >
Encoding:
Text File  |  1990-03-20  |  47.6 KB  |  1,698 lines

  1. Path: uunet!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!brutus.cs.uiuc.edu!apple!sun-barr!newstop!sun!icsib12.Berkeley.EDU
  2. From: stolcke@icsib12.Berkeley.EDU (Andreas Stolcke)
  3. Newsgroups: comp.sources.x
  4. Subject: v06i038: xnetload, Patch1
  5. Message-ID: <133251@sun.Eng.Sun.COM>
  6. Date: 21 Mar 90 10:27:28 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1687
  9. Approved: argv@sun.com
  10.  
  11. Submitted-by: stolcke@icsib12.Berkeley.EDU (Andreas Stolcke)
  12. Posting-number: Volume 6, Issue 38
  13. Archive-name: xnetld/patch1
  14.  
  15. [ xnetload has appeared in this newsgroup before, but not the R4 version.
  16.   this patch brings the R4 version up to date, but can't be applied to
  17.   the previous version, so we're resetting to patch 1 (I guess)  --dan ]
  18.  
  19.  
  20. The following is a patch to xnetload, patchlevel 0 (from the R4 distribution).
  21. It allows the Sun RPC mechanism to be used to get the load from remote
  22. machines, instead of the rwho database.
  23.  
  24. The patch contains a README file, a patch to be applied to the original
  25. xnetload source, and a copy of the R3 Load widget, which is required
  26. for compilation under R4, but wasn't included in the original distribution.
  27.  
  28. This patch is not official, but its posting was suggested by the original
  29. author, J. Michael Berkley <jmberkey@watnow.waterloo.edu>.  It will probably
  30. be incorporated in a future update, not to expected too soon, according to
  31. the author.
  32.  
  33. Have fun!
  34.  
  35. Andreas
  36.  
  37. #!/bin/sh
  38. # This is a shell archive, meaning:
  39. # 1. Remove everything above the #!/bin/sh line.
  40. # 2. Save the resulting text in a file.
  41. # 3. Execute the file with /bin/sh (not csh) to create the files:
  42. #    README.RUPRPC
  43. #    RUPRPC.patch
  44. #    X11/Load.c
  45. #    X11/Load.c.dist
  46. #    X11/Load.h
  47. #    X11/LoadP.h
  48. # This archive created: Mon Mar 19 17:07:43 1990
  49. export PATH; PATH=/bin:$PATH
  50. if test -f 'README.RUPRPC'
  51. then
  52.     echo shar: over-writing existing file "'README.RUPRPC'"
  53. fi
  54. cat << \SHAR_EOF > 'README.RUPRPC'
  55.  
  56. Changes to xnetload to use rup-like RPC for remote load:
  57. =====================================================a=
  58.  
  59. By defining RUPRPC at compile time the getload function uses Sun's RPC
  60. mechanism to obtain remote loads from rstatd(8). This is likely to be the
  61. better alternative on systems where this service is available, since rwhod(8)
  62. may have prohibitive impact on network load and is not run at
  63. many sites for this reason.
  64.  
  65. Patches:
  66.  
  67. getload.c:
  68.  
  69.     With RUPRPC defined, getload uses a simple callrpc(). The details
  70.     of the mechanism are gleaned from the rup(1) source.
  71.     Note that xnetload expects getload to return the load value in
  72.     rwhod format, hence the actual load value is multiplied by 100
  73.     and truncated to a integer.
  74.  
  75. xnetload.c:
  76.  
  77.     Allow defining DEFREMUPDATE in the Makefile.
  78.  
  79. Imakefile:
  80.  
  81.     When compiling on Suns, the RPC-based remote load mechanism is
  82.     enabled and the default update interval set to 5 seconds (same as
  83.     for local load).
  84.  
  85.     A little recursive-make hack ensures that getload.c is compiled with
  86.     Sun's cc compiler. gcc doesn't like some of the syntax in
  87.     header files in /usr/include/rpc and /usr/include/rpcsvc.
  88.     The CCOPTIONS definition in the recursive call to make may have to
  89.     be patched to match the CCOPTIONS used for gcc (e.g., put in
  90.     -f68881 if gcc uses -m68881).
  91.  
  92.     The old X11R3 Load widget code and header files are in subdirectory
  93.     X11, and the Imakefile takes that into account.
  94.  
  95. Bugs:
  96.     Still uses R3 Load widget.
  97.  
  98.     The callrpc() function used to perform the RPC does not allow
  99.     timeout specification.  So when a machine is down or not running
  100.     rstatd, xnetload will discover that only after a delay of several
  101.     (tens of) seconds.  When monitoring more than one machine,
  102.     all the displays will be slowed down by this delay.
  103.  
  104.                     Andreas Stolcke
  105.                     stolcke@icsi.berkeley.edu
  106.                     2/21/90
  107.  
  108. SHAR_EOF
  109. if test -f 'RUPRPC.patch'
  110. then
  111.     echo shar: over-writing existing file "'RUPRPC.patch'"
  112. fi
  113. cat << \SHAR_EOF > 'RUPRPC.patch'
  114. *** Imakefile.dist    Tue Oct 10 08:06:25 1989
  115. --- Imakefile    Wed Feb 21 12:27:04 1990
  116. ***************
  117. *** 22,47 ****
  118.   # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  119.   #
  120.   
  121.   #
  122.   # Since xnetload finds the local machine's load using the standard Load
  123.   # widget stuff, it needs to be able to read kmem, i.e.  setgid kmem.  If
  124.   # you do not want this, then define NOLOCAL
  125. ! #        DEFINES = -O -DNOLOCAL
  126.   
  127. !        INCLUDES = -I$(TOP) -I$(TOP)/X11
  128.   
  129.   # Dynix doesn't have -L option on load, but I have left changing the
  130.   # XLIB specification up to individual sites.  Dynix and our Sun 3.5
  131.   # don't come with a memcpy, so you'll have to add in whichever library
  132.   # has memcpy.
  133. ! /* LOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB) */
  134. ! LOCAL_LIBRARIES = -L/usr/software/X11/lib -lXaw -lXmu -lXt -lX11
  135.   
  136. !            SRCS = xnetload.c getload.o
  137. !            OBJS = xnetload.o getload.o
  138.   
  139.      INSTALLFLAGS = $(INSTKMEMFLAGS)
  140.   
  141. ! all: xnetload
  142.   
  143. ! SingleProgramTarget(xnetload,$(OBJS),,$(LOCAL_LIBRARIES))
  144. --- 22,63 ----
  145.   # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  146.   #
  147.   
  148. +      COMPATFLAGS = -DXAW_BC
  149.   #
  150.   # Since xnetload finds the local machine's load using the standard Load
  151.   # widget stuff, it needs to be able to read kmem, i.e.  setgid kmem.  If
  152.   # you do not want this, then define NOLOCAL
  153. ! #if SunOSPlatform
  154. !       RUPDEFINES = -DRUPRPC -DDEFREMUPDATE=5 /* -DDEBUGGING */
  155. !    SYS_LIBRARIES = -lrpcsvc
  156. ! #endif
  157. !          DEFINES = /* -DNOLOCAL */ $(RUPDEFINES)
  158.   
  159. ! #       INCLUDES = -I$(TOP) -I$(TOP)/X11
  160.   
  161.   # Dynix doesn't have -L option on load, but I have left changing the
  162.   # XLIB specification up to individual sites.  Dynix and our Sun 3.5
  163.   # don't come with a memcpy, so you'll have to add in whichever library
  164.   # has memcpy.
  165. ! LOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
  166.   
  167. !            SRCS = xnetload.c getload.c X11/Load.c
  168. !            OBJS = xnetload.o getload.o Load.o
  169.   
  170.      INSTALLFLAGS = $(INSTKMEMFLAGS)
  171.   
  172. ! ComplexProgramTarget(xnetload)
  173.   
  174. ! Load.o:        X11/Load.c
  175. !         $(CC) -c $(CFLAGS) X11/Load.c
  176. ! #if SunOSPlatform
  177. ! #if HasGcc    /* GCC is too picky about syntax in Sun RPC header files */
  178. ! getload.o:    getload.c
  179. !         @if [ "$(CC)" != cc ] ;\
  180. !         then $(MAKE) CC=cc CCOPTIONS= getload.o ;\
  181. !         else cmd="$(CC) -c $(CFLAGS) getload.c"; echo $$cmd; $$cmd ;\
  182. !         fi
  183. ! #endif
  184. ! #endif
  185. *** getload.c.dist    Tue Oct 10 08:06:26 1989
  186. --- getload.c    Wed Feb 21 13:21:55 1990
  187. ***************
  188. *** 32,37 ****
  189. --- 32,87 ----
  190.   #include <sys/types.h>
  191.   #include <sys/time.h>
  192.   
  193. + #ifdef RUPRPC
  194. + #include <sys/param.h>
  195. + #include <sys/stat.h>
  196. + #include <sys/socket.h>
  197. + #include <rpcsvc/rstat.h>
  198. + #include <rpc/rpc.h>
  199. + #include <rpc/pmap_clnt.h>
  200. + int
  201. + getload(host)
  202. +     char *host;
  203. + {
  204. +     enum clnt_stat err;
  205. +     struct statstime sw;
  206. +     
  207. + #ifdef DEBUGGING
  208. +     fprintf(stderr, "xnetload: %s: ", host);
  209. +     fflush(stderr);
  210. + #endif
  211. +     err = (enum clnt_stat)callrpc(host, RSTATPROG, RSTATVERS_TIME,
  212. +         RSTATPROC_STATS, xdr_void, 0, xdr_statstime, &sw);
  213. +     if (err != RPC_SUCCESS)
  214. +          if (err == RPC_PROGVERSMISMATCH) {
  215. +         if (err = (enum clnt_stat)callrpc(host, RSTATPROG,
  216. +             RSTATVERS_SWTCH, RSTATPROC_STATS, xdr_void, 0,
  217. +             xdr_statsswtch, &sw)) {
  218. + #ifndef DEBUGGING
  219. +             fprintf(stderr, "xnetload: %s: ", host);
  220. + #endif
  221. +             clnt_perrno(err);
  222. +             fprintf(stderr, "\n");
  223. +             return( -1 );
  224. +         }
  225. +     }
  226. +     else {
  227. + #ifndef DEBUGGING
  228. +         fprintf(stderr, "xnetload: %s: ", host);
  229. + #endif
  230. +         clnt_perrno(err);
  231. +         fprintf(stderr, "\n");
  232. +         return( -1 );
  233. +     }
  234. + #ifdef DEBUGGING
  235. +     fprintf(stderr, "%lf\n", (double)sw.avenrun[0]/FSCALE);
  236. + #endif
  237. +     return( (double)sw.avenrun[0]/FSCALE * 100.0);
  238. + }
  239. + #else /* no RUPRPC */
  240.   /* Dynix doesn't have an rwhod.h file, so here's the struct for that system */
  241.   #ifdef sequent
  242.   struct  outmp {
  243. ***************
  244. *** 113,115 ****
  245. --- 163,166 ----
  246.       }
  247.       return(0);        /* couldn't read load if here */
  248.   }
  249. + #endif
  250. SHAR_EOF
  251. if test -f 'X11/Load.c'
  252. then
  253.     echo shar: over-writing existing file "'X11/Load.c'"
  254. fi
  255. cat << \SHAR_EOF > 'X11/Load.c'
  256. #ifndef lint
  257. static char Xrcsid[] = "$XConsortium: Load.c,v 1.44 88/10/17 15:11:38 jim Exp $";
  258. #endif
  259.  
  260. /***********************************************************
  261. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  262. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  263.  
  264.                         All Rights Reserved
  265.  
  266. Permission to use, copy, modify, and distribute this software and its 
  267. documentation for any purpose and without fee is hereby granted, 
  268. provided that the above copyright notice appear in all copies and that
  269. both that copyright notice and this permission notice appear in 
  270. supporting documentation, and that the names of Digital or MIT not be
  271. used in advertising or publicity pertaining to distribution of the
  272. software without specific, written prior permission.  
  273.  
  274. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  275. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  276. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  277. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  278. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  279. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  280. SOFTWARE.
  281.  
  282. ******************************************************************/
  283.  
  284. #ifdef apollo
  285. #include "/sys/ins/base.ins.c"
  286. #include "/sys/ins/time.ins.c"
  287. typedef struct {
  288.     short        proc2_$state_t; /* ready, waiting, etc. */
  289.     pinteger    usr;        /* user sr */
  290.     linteger    upc;        /* user pc */
  291.     linteger    usp;        /* user stack pointer */
  292.     linteger    usb;        /* user sb ptr (A6) */
  293.     time_$clock_t    cpu_total;    /* cumulative cpu used by process */
  294.     unsigned short    priority;    /* process priority */
  295.     } proc1_$info_t;
  296.  
  297. std_$call void proc1_$get_cput();
  298. std_$call void proc1_$get_info();
  299. #endif /* apollo */
  300.  
  301. #include <X11/IntrinsicP.h>
  302. #include <X11/Xos.h>
  303. #include <X11/StringDefs.h>
  304. #include <X11/Xmu.h>
  305. #include <stdio.h>
  306.  
  307. #ifndef macII
  308. #ifndef apollo
  309. #ifndef LOADSTUB
  310. #include <nlist.h>
  311. #endif /* LOADSTUB */
  312. #endif /* apollo */
  313. #endif /* macII */
  314.  
  315. #ifdef sun
  316. #include <sys/param.h>
  317. #endif
  318. #ifdef NeXT
  319. #include <sys/param.h>
  320. #endif
  321. #ifdef mips
  322. #include <sys/fixpoint.h>
  323. #endif
  324. #ifdef sequent
  325. #include <sys/vm.h>
  326. #endif /* sequent */
  327. #include <X11/LoadP.h>
  328. #ifdef macII
  329. #include <a.out.h>
  330. #include <sys/var.h>
  331. #define X_AVENRUN 0
  332. #define fxtod(i) (vec[i].high+(vec[i].low/65536.0))
  333. struct lavnum {
  334.     unsigned short high;
  335.     unsigned short low;
  336. };
  337. #endif macII
  338. #ifdef UTEK
  339. #define FSCALE    100.0
  340. #endif
  341. #ifdef sequent
  342. #define FSCALE    1000.0
  343. #endif
  344.  
  345. extern long lseek();
  346. extern void exit();
  347.  
  348. /* Private Data */
  349.  
  350. static void GetLoadPoint();
  351. static XtCallbackProc getLoadProc = GetLoadPoint;
  352.  
  353. #define offset(field) XtOffset(LoadWidget,load.field)
  354. #define goffset(field) XtOffset(Widget,core.field)
  355.  
  356. static Dimension defDim = 120;
  357. static int defInterval = 5;
  358. static int defScale = 1;
  359.  
  360. static XtResource resources[] = {
  361.     {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
  362.     goffset(width), XtRDimension, (caddr_t)&defDim},
  363.     {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
  364.     goffset(height), XtRDimension, (caddr_t)&defDim},
  365.     {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
  366.     goffset(background_pixel), XtRString, "White"},
  367.     {XtNupdate, XtCInterval, XtRInt, sizeof(int),
  368.         offset(update), XtRInt, (caddr_t)&defInterval},
  369.     {XtNscale, XtCScale, XtRInt, sizeof(int),
  370.         offset(scale), XtRInt, (caddr_t)&defScale},
  371.     {XtNminScale, XtCScale, XtRInt, sizeof(int),
  372.         offset(min_scale), XtRInt, (caddr_t)&defScale},
  373.     {XtNlabel, XtCLabel, XtRString, sizeof(char *),
  374.         offset(text), XtRString, NULL},
  375.     {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  376.         offset(fgpixel), XtRString, "Black"},
  377.     {XtNhighlight, XtCForeground, XtRPixel, sizeof(Pixel),
  378.         offset(hipixel), XtRString, "Black"},
  379.     {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  380.         offset(font), XtRString, XtDefaultFont},
  381.     {XtNgetLoadProc, XtCCallback, XtRCallback, sizeof(caddr_t),
  382.         offset(get_load), XtRFunction, (caddr_t)&getLoadProc},
  383.     {XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
  384.     offset (reverse_video), XtRString, "FALSE"},
  385. };
  386.  
  387. #undef offset
  388. #undef goffset
  389.  
  390. static void ClassInitialize();
  391. static void Initialize(), Realize(), Destroy(), Redisplay();
  392. static Boolean SetValues();
  393. static int repaint_window();
  394.  
  395. LoadClassRec loadClassRec = {
  396.     { /* core fields */
  397.     /* superclass        */    &widgetClassRec,
  398.     /* class_name        */    "Load",
  399.     /* size            */    sizeof(LoadRec),
  400.     /* class_initialize        */    ClassInitialize,
  401.     /* class_part_initialize    */    NULL,
  402.     /* class_inited        */    FALSE,
  403.     /* initialize        */    Initialize,
  404.     /* initialize_hook        */    NULL,
  405.     /* realize            */    Realize,
  406.     /* actions            */    NULL,
  407.     /* num_actions        */    0,
  408.     /* resources        */    resources,
  409.     /* num_resources        */    XtNumber(resources),
  410.     /* xrm_class        */    NULL,
  411.     /* compress_motion        */    TRUE,
  412.     /* compress_exposure    */    TRUE,
  413.     /* compress_enterleave    */    TRUE,
  414.     /* visible_interest        */    FALSE,
  415.     /* destroy            */    Destroy,
  416.     /* resize            */    NULL,
  417.     /* expose            */    Redisplay,
  418.     /* set_values        */    SetValues,
  419.     /* set_values_hook        */    NULL,
  420.     /* set_values_almost    */    NULL,
  421.     /* get_values_hook        */    NULL,
  422.     /* accept_focus        */    NULL,
  423.     /* version            */    XtVersion,
  424.     /* callback_private        */    NULL,
  425.     /* tm_table            */    NULL,
  426.     /* query_geometry        */    XtInheritQueryGeometry,
  427.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  428.     /* extension        */    NULL
  429.     }
  430. };
  431.  
  432. WidgetClass loadWidgetClass = (WidgetClass) &loadClassRec;
  433.  
  434. /****************************************************************
  435.  *
  436.  * Private Procedures
  437.  *
  438.  ****************************************************************/
  439.  
  440. static void draw_it();
  441.  
  442. static void ClassInitialize()
  443. {
  444.     XtAddConverter( XtRFunction, XtRCallback, XmuCvtFunctionToCallback,
  445.             NULL, 0 );
  446. }
  447.  
  448. /* ARGSUSED */
  449. static void Initialize (greq, gnew)
  450.     Widget greq, gnew;
  451. {
  452.     LoadWidget w = (LoadWidget)gnew;
  453.     XtGCMask    valuemask;
  454.     XGCValues    myXGCV;
  455.  
  456.     /*
  457.      * set the colors if reverse video; these are the colors used:
  458.      *
  459.      *     background - paper        white
  460.      *     foreground - text, ticks    black
  461.      *     border - border        black (foreground)
  462.      *
  463.      * This doesn't completely work since the parent has already made up a 
  464.      * border.  Sigh.
  465.      */
  466.     if (w->load.reverse_video) {
  467.     Pixel fg = w->load.fgpixel;
  468.     Pixel bg = w->core.background_pixel;
  469.  
  470.     if (w->core.border_pixel == fg) w->core.border_pixel = bg;
  471.     if (w->load.hipixel == w->load.fgpixel) w->load.hipixel = bg;
  472.     w->load.fgpixel = bg;
  473.     w->core.background_pixel = fg;
  474.     }
  475.  
  476.     valuemask = GCForeground | GCBackground;
  477.     myXGCV.foreground = w->load.fgpixel;
  478.     if (w->load.font) {
  479.       myXGCV.font = w->load.font->fid;
  480.       valuemask |= GCFont;
  481.     }
  482.     myXGCV.background = w->core.background_pixel;
  483.     w->load.fgGC = XtGetGC(gnew, valuemask, &myXGCV);
  484.     myXGCV.foreground = w->load.hipixel;
  485.     w->load.hiGC = XtGetGC(gnew, valuemask, &myXGCV);
  486.  
  487.     /*
  488.      * Note that the second argument is a GCid -- QueryFont accepts a GCid and
  489.      * returns the curently contained font.
  490.      */
  491.     if (w->load.font == NULL)
  492.       w->load.font = XQueryFont (XtDisplay (w),
  493.                   XGContextFromGC (DefaultGCOfScreen (XtScreen (w))));
  494.  
  495.     if (w->load.update > 0)
  496.         w->load.interval_id =
  497.         XtAddTimeOut(w->load.update*1000, draw_it, (caddr_t)gnew);
  498.     else
  499.         w->load.interval_id = 0;
  500.  
  501.     w->load.interval = 0;
  502.     w->load.max_value = 0.0;
  503. }
  504.  
  505. static void Realize (gw, valueMask, attrs)
  506.      Widget gw;
  507.      XtValueMask *valueMask;
  508.      XSetWindowAttributes *attrs;
  509. {
  510.      XtCreateWindow( gw, (unsigned)InputOutput, (Visual *)CopyFromParent,
  511.              *valueMask, attrs );
  512. }
  513.  
  514. static void Destroy (gw)
  515.      Widget gw;
  516. {
  517.      LoadWidget w = (LoadWidget)gw;
  518.      if (w->load.interval_id) XtRemoveTimeOut (w->load.interval_id);
  519.      XtDestroyGC (w->load.fgGC);
  520.      XtDestroyGC (w->load.hiGC);
  521. }
  522.  
  523. /* ARGSUSED */
  524. static void Redisplay(gw, event, region)
  525.      Widget gw;
  526.      XEvent *event;
  527.      Region region;
  528. {
  529.      (void) repaint_window ((LoadWidget)gw, event->xexpose.x,
  530.                 event->xexpose.width);
  531. }
  532.  
  533. /* ARGSUSED */
  534. static void draw_it(client_data, id)
  535.      caddr_t client_data;
  536.      XtIntervalId id;        /* unused */
  537. {
  538.         LoadWidget w = (LoadWidget)client_data;
  539.     double value;
  540.  
  541.     if (w->load.update > 0)
  542.         w->load.interval_id =
  543.         XtAddTimeOut(w->load.update*1000, draw_it, (caddr_t)w);
  544.  
  545.     if (w->load.interval >= w->core.width) {
  546.         XClearWindow(XtDisplay(w), XtWindow(w));
  547.         w->load.interval = repaint_window(w, 0, w->core.width);
  548.     }
  549.  
  550.     /* Get the value, stash the point and draw corresponding line. */
  551.  
  552.     XtCallCallbacks( (Widget)w, XtNgetLoadProc, (caddr_t)&value );
  553.  
  554.     /* Keep w->load.max_value up to date, and if this data point is off the
  555.        graph, change the scale to make it fit. */
  556.     if (value > w->load.max_value) {
  557.         w->load.max_value = value;
  558.         if (w->load.max_value > w->load.scale) {
  559.         w->load.scale = ((int)w->load.max_value) + 1;
  560.         XClearWindow(XtDisplay(w), XtWindow(w));
  561.         w->load.interval = repaint_window(w, 0, w->core.width);
  562.         }
  563.     }
  564.  
  565.     w->load.valuedata[w->load.interval] = value;
  566.     if (XtIsRealized((Widget)w)) {
  567.         XDrawLine(XtDisplay(w), XtWindow(w), w->load.fgGC,
  568.           w->load.interval, w->core.height, w->load.interval, 
  569.             (int)(w->core.height - (w->core.height * value)
  570. /w->load.scale));
  571.         XFlush(XtDisplay(w));            /* Flush output buffers */
  572.     }
  573.     w->load.interval++;            /* Next point */
  574. } /* draw_it */
  575.  
  576. /* Blts data according to current size, then redraws the load average window.
  577.  * Next represents the number of valid points in data.  Returns the (possibly)
  578.  * adjusted value of next.  If next is 0, this routine draws an empty window
  579.  * (scale - 1 lines for graph).  If next is less than the current window width,
  580.  * the returned value is identical to the initial value of next and data is
  581.  * unchanged.  Otherwise keeps half a window's worth of data.  If data is
  582.  * changed, then w->load.max_value is updated to reflect the largest data point.
  583.  */
  584.  
  585. static int repaint_window(w, left, width)
  586.     LoadWidget w;
  587.     int left, width;
  588. {
  589.     register int i, j;
  590.     register int next = w->load.interval;
  591.     int scale = w->load.scale;
  592.     extern void bcopy();
  593.  
  594.     if (next >= w->core.width) {
  595.     j = w->core.width >> 1;
  596.     bcopy((char *)(w->load.valuedata + next - j),
  597.           (char *)(w->load.valuedata), j * sizeof(double));
  598.     next = j;
  599.     /* Since we just lost some data, recompute the w->load.max_value. */
  600.     w->load.max_value = 0.0;
  601.     for (i = 0; i < next; i++) {
  602.         if (w->load.valuedata[i] > w->load.max_value) 
  603.           w->load.max_value = w->load.valuedata[i];
  604.     }
  605.     left = 0;
  606.     width = next; 
  607.     }
  608.  
  609.     /* Compute the minimum scale required to graph the data, but don't go
  610.        lower than min_scale. */
  611.     if (w->load.interval != 0 || scale <= (int)w->load.max_value)
  612.       scale = ((int) (w->load.max_value)) + 1;
  613.     if (scale < w->load.min_scale)
  614.       scale = w->load.min_scale;
  615.     if (scale != w->load.scale) {
  616.       w->load.scale = scale;
  617.       left = 0;
  618.       width = next;
  619.       if (XtIsRealized ((Widget) w)) {
  620.     XClearWindow (XtDisplay (w), XtWindow (w));
  621.       }
  622.     }
  623.  
  624.     if (XtIsRealized((Widget)w)) {
  625.     Display *dpy = XtDisplay(w);
  626.     Window win = XtWindow(w);
  627.  
  628.     if (w->load.text) {
  629.         /* Print hostname */
  630.         XDrawString(dpy, win, w->load.hiGC, 2, 
  631.              2 + w->load.font->ascent, w->load.text, strlen(w->load.text));
  632.     }
  633.  
  634.     /* Draw graph reference lines */
  635.     for (i = 1; i < w->load.scale; i++) {
  636.         j = (i * w->core.height) / w->load.scale;
  637.         XDrawLine(dpy, win, w->load.hiGC, 0, j,
  638.               (int)w->core.width, j);
  639.     }
  640.  
  641.     if (next < (width += left)) width = next;
  642.     /* Draw data point lines. */
  643.     for (i = left; i < width; i++)
  644.         XDrawLine(dpy, win, w->load.fgGC, i, w->core.height,
  645.           i, (int)(w->core.height-(w->load.valuedata[i] * w->core.height)
  646.               /w->load.scale));
  647.         }
  648.  
  649.     return(next);
  650. }
  651.  
  652. #if apollo
  653. /* ARGSUSED */
  654. static void GetLoadPoint( w, closure, call_data )
  655.      Widget    w;        /* unused */
  656.      caddr_t    closure;    /* unused */
  657.      caddr_t    call_data;    /* pointer to (double) return value */
  658. {
  659.      static Bool    firstTime = TRUE;
  660.      static int     lastNullCpu;
  661.      static int     lastClock;
  662.      time_$clock_t  timeNow;
  663.      double         temp;
  664.      proc1_$info_t  info;
  665.      status_$t      st;
  666.  
  667.      proc1_$get_info( (short) 2, info, st );
  668.      time_$clock( timeNow );
  669.  
  670.      if (firstTime)
  671.      {
  672.          *(double *)call_data = 1.0;
  673.          firstTime = FALSE;
  674.      }
  675.      else {
  676.          temp = info.cpu_total.low32 - lastNullCpu;
  677.          *(double *)call_data = 1.0 - temp / (timeNow.low32 - lastClock);
  678.      }
  679.  
  680.      lastClock = timeNow.low32;
  681.      lastNullCpu = info.cpu_total.low32;
  682. }
  683. #else
  684. #ifdef LOADSTUB
  685.  
  686. /* ARGSUSED */
  687. static void GetLoadPoint( w, closure, call_data )
  688.      Widget    w;        /* unused */
  689.      caddr_t    closure;    /* unused */
  690.      caddr_t    call_data;    /* pointer to (double) return value */
  691. {
  692.     *(double *)call_data = 1.0;
  693. }
  694.  
  695. #else /* LOADSTUB */
  696.  
  697. #ifndef KMEM_FILE
  698. #define KMEM_FILE "/dev/kmem"
  699. #endif
  700.  
  701. #ifndef KERNEL_FILE
  702. #ifdef CRAY
  703. #define KERNEL_FILE "/unicos"
  704. #endif /* CRAY */
  705. #ifdef hpux
  706. #define KERNEL_FILE "/hp-ux"
  707. #endif /* hpux */
  708. #ifdef macII
  709. #define KERNEL_FILE "/unix"
  710. #endif /* macII */
  711. #ifdef mips
  712. # ifdef SYSTYPE_SYSV
  713. # define KERNEL_FILE "/unix"
  714. # else
  715. # define KERNEL_FILE "/vmunix"
  716. # endif /* SYSTYPE_SYSV */
  717. #endif /* mips */
  718. #ifdef sequent
  719. #define KERNEL_FILE "/dynix"
  720. #endif /* sequent */
  721.  
  722. /*
  723.  * provide default for everyone else
  724.  */
  725. #ifndef KERNEL_FILE
  726. #define KERNEL_FILE "/vmunix"
  727. #endif /* KERNEL_FILE */
  728. #endif /* KERNEL_FILE */
  729.  
  730.  
  731. #ifndef KERNEL_LOAD_VARIABLE
  732. #ifdef CRAY
  733. #define KERNEL_LOAD_VARIABLE "avenrun"
  734. #undef n_type
  735. #define n_type n_value
  736. #endif /* CRAY */
  737. #ifdef hpux
  738. #ifdef hp9000s800
  739. #define KERNEL_LOAD_VARIABLE "avenrun"
  740. #endif /* hp9000s800 */
  741. #endif /* hpux */
  742. #ifdef mips
  743. # ifdef SYSTYPE_SYSV
  744. # define KERNEL_LOAD_VARIABLE "avenrun"
  745. # else
  746. # define KERNEL_LOAD_VARIABLE "_avenrun"
  747. # endif /* SYSTYPE_SYSV */
  748. #endif /* mips */
  749. #ifdef sequent
  750. #define KERNEL_FILE "/dynix"
  751. #endif /* sequent */
  752. /*
  753.  * provide default for everyone else
  754.  */
  755. #ifndef KERNEL_LOAD_VARIABLE
  756. #define KERNEL_LOAD_VARIABLE "_avenrun"
  757. #endif /* KERNEL_LOAD_VARIABLE */
  758. #endif /* KERNEL_LOAD_VARIABLE */
  759.  
  760. #ifdef macII
  761. static struct var v;
  762. static struct nlist nl[2];
  763. static struct lavnum vec[3];
  764. #else /* not macII */
  765. #ifdef NeXT
  766. static struct nlist namelist[] = {        /* namelist for vmunix grubbing */
  767. #define LOADAV 0
  768.     {{KERNEL_LOAD_VARIABLE}},
  769.     {{0}}
  770. };
  771. #else
  772. static struct nlist namelist[] = {        /* namelist for vmunix grubbing */
  773. #define LOADAV 0
  774.     {KERNEL_LOAD_VARIABLE},
  775.     {0}
  776. };
  777. #endif
  778. #endif /* macII */
  779.  
  780.  
  781. /* ARGSUSED */
  782. static void GetLoadPoint( w, closure, call_data )
  783.      Widget    w;        /* unused */
  784.      caddr_t    closure;    /* unused */
  785.      caddr_t    call_data;    /* pointer to (double) return value */
  786. {
  787.       double *loadavg = (double *)call_data;
  788.     static int init = 0;
  789.     static kmem;
  790.     static long loadavg_seek;
  791. #ifdef macII
  792.         extern nlist();
  793.  
  794.         if(!init)   {
  795.             int i;
  796.  
  797.             strcpy(nl[0].n_name, "avenrun");
  798.             nl[1].n_name[0] = '\0';
  799.  
  800.             kmem = open(KMEM_FILE, O_RDONLY);
  801.             if (kmem < 0) {
  802.             xload_error("cannot open", KMEM_FILE);
  803.             }
  804.  
  805.             uvar(&v);
  806.  
  807.             if (nlist( KERNEL_FILE, nl) != 0) {
  808.         xload_error("cannot get name list from", KERNEL_FILE);
  809.             }
  810.             for (i = 0; i < 2; i++) {
  811.                 nl[i].n_value = (int)nl[i].n_value - v.v_kvoffset;
  812.             }
  813.             init = 1;
  814.         }
  815. #else /* not macII */
  816.     extern void nlist();
  817.     
  818.     if(!init)   {
  819.         nlist( KERNEL_FILE, namelist);
  820.         if (namelist[LOADAV].n_type == 0){
  821.         xload_error("cannot get name list from", KERNEL_FILE);
  822.         exit(-1);
  823.         }
  824.         loadavg_seek = namelist[LOADAV].n_value;
  825. # if defined(mips) && defined(SYSTYPE_SYSV)
  826.         loadavg_seek &= 0x7fffffff;
  827. # endif /* mips && SYSTYPE_SYSV */
  828.         kmem = open(KMEM_FILE, O_RDONLY);
  829.         if (kmem < 0) xload_error("cannot open", KMEM_FILE);
  830.         init = 1;
  831.     }
  832.     
  833.  
  834.     (void) lseek(kmem, loadavg_seek, 0);
  835. #endif /* macII */
  836. #if defined(sun) || defined (UTEK) || defined(sequent) || defined(NeXT)
  837.     {
  838.         long temp;
  839.         (void) read(kmem, (char *)&temp, sizeof(long));
  840.         *loadavg = (double)temp/FSCALE;
  841.     }
  842. #else /* else not sun */
  843. # ifdef macII
  844.         {
  845.                 lseek(kmem, (long)nl[X_AVENRUN].n_value, 0);
  846.                 read(kmem, vec, 3*sizeof(struct lavnum));
  847.                 *loadavg = fxtod(0);
  848.         }
  849. # else /* else not macII */
  850. #  ifdef mips
  851.     {
  852.         fix temp;
  853.         (void) read(kmem, (char *)&temp, sizeof(fix));
  854.         *loadavg = FIX_TO_DBL(temp);
  855.     }
  856. #  else /* not mips */
  857.     (void) read(kmem, (char *)loadavg, sizeof(double));
  858. #  endif /* mips */
  859. # endif /* macII */
  860. #endif /* sun */
  861.     return;
  862. }
  863. #endif /* LOADSTUB */
  864. #endif /* apollo */
  865.  
  866. static xload_error(str1, str2)
  867. char *str1, *str2;
  868. {
  869.     (void) fprintf(stderr,"xload: %s %s\n", str1, str2);
  870.     exit(-1);
  871. }
  872.  
  873. /* ARGSUSED */
  874. static Boolean SetValues (current, request, new)
  875.     Widget current, request, new;
  876. {
  877.     LoadWidget old = (LoadWidget)current;
  878.     LoadWidget w = (LoadWidget)new;
  879.     if (w->load.update != old->load.update) {
  880.     XtRemoveTimeOut (old->load.interval_id);
  881.     w->load.interval_id =
  882.         XtAddTimeOut(w->load.update*1000, draw_it, (caddr_t)w);
  883.     }
  884.  
  885.     return( FALSE );
  886. }
  887. SHAR_EOF
  888. if test -f 'X11/Load.c.dist'
  889. then
  890.     echo shar: over-writing existing file "'X11/Load.c.dist'"
  891. fi
  892. cat << \SHAR_EOF > 'X11/Load.c.dist'
  893. #ifndef lint
  894. static char Xrcsid[] = "$XConsortium: Load.c,v 1.44 88/10/17 15:11:38 jim Exp $";
  895. #endif
  896.  
  897. /***********************************************************
  898. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  899. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  900.  
  901.                         All Rights Reserved
  902.  
  903. Permission to use, copy, modify, and distribute this software and its 
  904. documentation for any purpose and without fee is hereby granted, 
  905. provided that the above copyright notice appear in all copies and that
  906. both that copyright notice and this permission notice appear in 
  907. supporting documentation, and that the names of Digital or MIT not be
  908. used in advertising or publicity pertaining to distribution of the
  909. software without specific, written prior permission.  
  910.  
  911. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  912. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  913. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  914. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  915. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  916. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  917. SOFTWARE.
  918.  
  919. ******************************************************************/
  920.  
  921. #ifdef apollo
  922. #include "/sys/ins/base.ins.c"
  923. #include "/sys/ins/time.ins.c"
  924. typedef struct {
  925.     short        proc2_$state_t; /* ready, waiting, etc. */
  926.     pinteger    usr;        /* user sr */
  927.     linteger    upc;        /* user pc */
  928.     linteger    usp;        /* user stack pointer */
  929.     linteger    usb;        /* user sb ptr (A6) */
  930.     time_$clock_t    cpu_total;    /* cumulative cpu used by process */
  931.     unsigned short    priority;    /* process priority */
  932.     } proc1_$info_t;
  933.  
  934. std_$call void proc1_$get_cput();
  935. std_$call void proc1_$get_info();
  936. #endif /* apollo */
  937.  
  938. #include <X11/IntrinsicP.h>
  939. #include <X11/Xos.h>
  940. #include <X11/StringDefs.h>
  941. #include <X11/Xmu.h>
  942. #include <stdio.h>
  943.  
  944. #ifndef macII
  945. #ifndef apollo
  946. #ifndef LOADSTUB
  947. #include <nlist.h>
  948. #endif /* LOADSTUB */
  949. #endif /* apollo */
  950. #endif /* macII */
  951.  
  952. #ifdef sun
  953. #include <sys/param.h>
  954. #endif
  955. #ifdef mips
  956. #include <sys/fixpoint.h>
  957. #endif
  958. #ifdef sequent
  959. #include <sys/vm.h>
  960. #endif /* sequent */
  961. #include <X11/LoadP.h>
  962. #ifdef macII
  963. #include <a.out.h>
  964. #include <sys/var.h>
  965. #define X_AVENRUN 0
  966. #define fxtod(i) (vec[i].high+(vec[i].low/65536.0))
  967. struct lavnum {
  968.     unsigned short high;
  969.     unsigned short low;
  970. };
  971. #endif macII
  972. #ifdef UTEK
  973. #define FSCALE    100.0
  974. #endif
  975. #ifdef sequent
  976. #define FSCALE    1000.0
  977. #endif
  978.  
  979. extern long lseek();
  980. extern void exit();
  981.  
  982. /* Private Data */
  983.  
  984. static void GetLoadPoint();
  985. static XtCallbackProc getLoadProc = GetLoadPoint;
  986.  
  987. #define offset(field) XtOffset(LoadWidget,load.field)
  988. #define goffset(field) XtOffset(Widget,core.field)
  989.  
  990. static Dimension defDim = 120;
  991. static int defInterval = 5;
  992. static int defScale = 1;
  993.  
  994. static XtResource resources[] = {
  995.     {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
  996.     goffset(width), XtRDimension, (caddr_t)&defDim},
  997.     {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
  998.     goffset(height), XtRDimension, (caddr_t)&defDim},
  999.     {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
  1000.     goffset(background_pixel), XtRString, "White"},
  1001.     {XtNupdate, XtCInterval, XtRInt, sizeof(int),
  1002.         offset(update), XtRInt, (caddr_t)&defInterval},
  1003.     {XtNscale, XtCScale, XtRInt, sizeof(int),
  1004.         offset(scale), XtRInt, (caddr_t)&defScale},
  1005.     {XtNminScale, XtCScale, XtRInt, sizeof(int),
  1006.         offset(min_scale), XtRInt, (caddr_t)&defScale},
  1007.     {XtNlabel, XtCLabel, XtRString, sizeof(char *),
  1008.         offset(text), XtRString, NULL},
  1009.     {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  1010.         offset(fgpixel), XtRString, "Black"},
  1011.     {XtNhighlight, XtCForeground, XtRPixel, sizeof(Pixel),
  1012.         offset(hipixel), XtRString, "Black"},
  1013.     {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  1014.         offset(font), XtRString, XtDefaultFont},
  1015.     {XtNgetLoadProc, XtCCallback, XtRCallback, sizeof(caddr_t),
  1016.         offset(get_load), XtRFunction, (caddr_t)&getLoadProc},
  1017.     {XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
  1018.     offset (reverse_video), XtRString, "FALSE"},
  1019. };
  1020.  
  1021. #undef offset
  1022. #undef goffset
  1023.  
  1024. static void ClassInitialize();
  1025. static void Initialize(), Realize(), Destroy(), Redisplay();
  1026. static Boolean SetValues();
  1027. static int repaint_window();
  1028.  
  1029. LoadClassRec loadClassRec = {
  1030.     { /* core fields */
  1031.     /* superclass        */    &widgetClassRec,
  1032.     /* class_name        */    "Load",
  1033.     /* size            */    sizeof(LoadRec),
  1034.     /* class_initialize        */    ClassInitialize,
  1035.     /* class_part_initialize    */    NULL,
  1036.     /* class_inited        */    FALSE,
  1037.     /* initialize        */    Initialize,
  1038.     /* initialize_hook        */    NULL,
  1039.     /* realize            */    Realize,
  1040.     /* actions            */    NULL,
  1041.     /* num_actions        */    0,
  1042.     /* resources        */    resources,
  1043.     /* num_resources        */    XtNumber(resources),
  1044.     /* xrm_class        */    NULL,
  1045.     /* compress_motion        */    TRUE,
  1046.     /* compress_exposure    */    TRUE,
  1047.     /* compress_enterleave    */    TRUE,
  1048.     /* visible_interest        */    FALSE,
  1049.     /* destroy            */    Destroy,
  1050.     /* resize            */    NULL,
  1051.     /* expose            */    Redisplay,
  1052.     /* set_values        */    SetValues,
  1053.     /* set_values_hook        */    NULL,
  1054.     /* set_values_almost    */    NULL,
  1055.     /* get_values_hook        */    NULL,
  1056.     /* accept_focus        */    NULL,
  1057.     /* version            */    XtVersion,
  1058.     /* callback_private        */    NULL,
  1059.     /* tm_table            */    NULL,
  1060.     /* query_geometry        */    XtInheritQueryGeometry,
  1061.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  1062.     /* extension        */    NULL
  1063.     }
  1064. };
  1065.  
  1066. WidgetClass loadWidgetClass = (WidgetClass) &loadClassRec;
  1067.  
  1068. /****************************************************************
  1069.  *
  1070.  * Private Procedures
  1071.  *
  1072.  ****************************************************************/
  1073.  
  1074. static void draw_it();
  1075.  
  1076. static void ClassInitialize()
  1077. {
  1078.     XtAddConverter( XtRFunction, XtRCallback, XmuCvtFunctionToCallback,
  1079.             NULL, 0 );
  1080. }
  1081.  
  1082. /* ARGSUSED */
  1083. static void Initialize (greq, gnew)
  1084.     Widget greq, gnew;
  1085. {
  1086.     LoadWidget w = (LoadWidget)gnew;
  1087.     XtGCMask    valuemask;
  1088.     XGCValues    myXGCV;
  1089.  
  1090.     /*
  1091.      * set the colors if reverse video; these are the colors used:
  1092.      *
  1093.      *     background - paper        white
  1094.      *     foreground - text, ticks    black
  1095.      *     border - border        black (foreground)
  1096.      *
  1097.      * This doesn't completely work since the parent has already made up a 
  1098.      * border.  Sigh.
  1099.      */
  1100.     if (w->load.reverse_video) {
  1101.     Pixel fg = w->load.fgpixel;
  1102.     Pixel bg = w->core.background_pixel;
  1103.  
  1104.     if (w->core.border_pixel == fg) w->core.border_pixel = bg;
  1105.     if (w->load.hipixel == w->load.fgpixel) w->load.hipixel = bg;
  1106.     w->load.fgpixel = bg;
  1107.     w->core.background_pixel = fg;
  1108.     }
  1109.  
  1110.     valuemask = GCForeground | GCBackground;
  1111.     myXGCV.foreground = w->load.fgpixel;
  1112.     if (w->load.font) {
  1113.       myXGCV.font = w->load.font->fid;
  1114.       valuemask |= GCFont;
  1115.     }
  1116.     myXGCV.background = w->core.background_pixel;
  1117.     w->load.fgGC = XtGetGC(gnew, valuemask, &myXGCV);
  1118.     myXGCV.foreground = w->load.hipixel;
  1119.     w->load.hiGC = XtGetGC(gnew, valuemask, &myXGCV);
  1120.  
  1121.     /*
  1122.      * Note that the second argument is a GCid -- QueryFont accepts a GCid and
  1123.      * returns the curently contained font.
  1124.      */
  1125.     if (w->load.font == NULL)
  1126.       w->load.font = XQueryFont (XtDisplay (w),
  1127.                   XGContextFromGC (DefaultGCOfScreen (XtScreen (w))));
  1128.  
  1129.     if (w->load.update > 0)
  1130.         w->load.interval_id =
  1131.         XtAddTimeOut(w->load.update*1000, draw_it, (caddr_t)gnew);
  1132.     else
  1133.         w->load.interval_id = 0;
  1134.  
  1135.     w->load.interval = 0;
  1136.     w->load.max_value = 0.0;
  1137. }
  1138.  
  1139. static void Realize (gw, valueMask, attrs)
  1140.      Widget gw;
  1141.      XtValueMask *valueMask;
  1142.      XSetWindowAttributes *attrs;
  1143. {
  1144.      XtCreateWindow( gw, (unsigned)InputOutput, (Visual *)CopyFromParent,
  1145.              *valueMask, attrs );
  1146. }
  1147.  
  1148. static void Destroy (gw)
  1149.      Widget gw;
  1150. {
  1151.      LoadWidget w = (LoadWidget)gw;
  1152.      if (w->load.interval_id) XtRemoveTimeOut (w->load.interval_id);
  1153.      XtDestroyGC (w->load.fgGC);
  1154.      XtDestroyGC (w->load.hiGC);
  1155. }
  1156.  
  1157. /* ARGSUSED */
  1158. static void Redisplay(gw, event, region)
  1159.      Widget gw;
  1160.      XEvent *event;
  1161.      Region region;
  1162. {
  1163.      (void) repaint_window ((LoadWidget)gw, event->xexpose.x,
  1164.                 event->xexpose.width);
  1165. }
  1166.  
  1167. /* ARGSUSED */
  1168. static void draw_it(client_data, id)
  1169.      caddr_t client_data;
  1170.      XtIntervalId id;        /* unused */
  1171. {
  1172.         LoadWidget w = (LoadWidget)client_data;
  1173.     double value;
  1174.  
  1175.     if (w->load.update > 0)
  1176.         w->load.interval_id =
  1177.         XtAddTimeOut(w->load.update*1000, draw_it, (caddr_t)w);
  1178.  
  1179.     if (w->load.interval >= w->core.width) {
  1180.         XClearWindow(XtDisplay(w), XtWindow(w));
  1181.         w->load.interval = repaint_window(w, 0, w->core.width);
  1182.     }
  1183.  
  1184.     /* Get the value, stash the point and draw corresponding line. */
  1185.  
  1186.     XtCallCallbacks( (Widget)w, XtNgetLoadProc, (caddr_t)&value );
  1187.  
  1188.     /* Keep w->load.max_value up to date, and if this data point is off the
  1189.        graph, change the scale to make it fit. */
  1190.     if (value > w->load.max_value) {
  1191.         w->load.max_value = value;
  1192.         if (w->load.max_value > w->load.scale) {
  1193.         w->load.scale = ((int)w->load.max_value) + 1;
  1194.         XClearWindow(XtDisplay(w), XtWindow(w));
  1195.         w->load.interval = repaint_window(w, 0, w->core.width);
  1196.         }
  1197.     }
  1198.  
  1199.     w->load.valuedata[w->load.interval] = value;
  1200.     if (XtIsRealized((Widget)w)) {
  1201.         XDrawLine(XtDisplay(w), XtWindow(w), w->load.fgGC,
  1202.           w->load.interval, w->core.height, w->load.interval, 
  1203.             (int)(w->core.height - (w->core.height * value)
  1204. /w->load.scale));
  1205.         XFlush(XtDisplay(w));            /* Flush output buffers */
  1206.     }
  1207.     w->load.interval++;            /* Next point */
  1208. } /* draw_it */
  1209.  
  1210. /* Blts data according to current size, then redraws the load average window.
  1211.  * Next represents the number of valid points in data.  Returns the (possibly)
  1212.  * adjusted value of next.  If next is 0, this routine draws an empty window
  1213.  * (scale - 1 lines for graph).  If next is less than the current window width,
  1214.  * the returned value is identical to the initial value of next and data is
  1215.  * unchanged.  Otherwise keeps half a window's worth of data.  If data is
  1216.  * changed, then w->load.max_value is updated to reflect the largest data point.
  1217.  */
  1218.  
  1219. static int repaint_window(w, left, width)
  1220.     LoadWidget w;
  1221.     int left, width;
  1222. {
  1223.     register int i, j;
  1224.     register int next = w->load.interval;
  1225.     int scale = w->load.scale;
  1226.     extern void bcopy();
  1227.  
  1228.     if (next >= w->core.width) {
  1229.     j = w->core.width >> 1;
  1230.     bcopy((char *)(w->load.valuedata + next - j),
  1231.           (char *)(w->load.valuedata), j * sizeof(double));
  1232.     next = j;
  1233.     /* Since we just lost some data, recompute the w->load.max_value. */
  1234.     w->load.max_value = 0.0;
  1235.     for (i = 0; i < next; i++) {
  1236.         if (w->load.valuedata[i] > w->load.max_value) 
  1237.           w->load.max_value = w->load.valuedata[i];
  1238.     }
  1239.     left = 0;
  1240.     width = next; 
  1241.     }
  1242.  
  1243.     /* Compute the minimum scale required to graph the data, but don't go
  1244.        lower than min_scale. */
  1245.     if (w->load.interval != 0 || scale <= (int)w->load.max_value)
  1246.       scale = ((int) (w->load.max_value)) + 1;
  1247.     if (scale < w->load.min_scale)
  1248.       scale = w->load.min_scale;
  1249.     if (scale != w->load.scale) {
  1250.       w->load.scale = scale;
  1251.       left = 0;
  1252.       width = next;
  1253.       if (XtIsRealized ((Widget) w)) {
  1254.     XClearWindow (XtDisplay (w), XtWindow (w));
  1255.       }
  1256.     }
  1257.  
  1258.     if (XtIsRealized((Widget)w)) {
  1259.     Display *dpy = XtDisplay(w);
  1260.     Window win = XtWindow(w);
  1261.  
  1262.     if (w->load.text) {
  1263.         /* Print hostname */
  1264.         XDrawString(dpy, win, w->load.hiGC, 2, 
  1265.              2 + w->load.font->ascent, w->load.text, strlen(w->load.text));
  1266.     }
  1267.  
  1268.     /* Draw graph reference lines */
  1269.     for (i = 1; i < w->load.scale; i++) {
  1270.         j = (i * w->core.height) / w->load.scale;
  1271.         XDrawLine(dpy, win, w->load.hiGC, 0, j,
  1272.               (int)w->core.width, j);
  1273.     }
  1274.  
  1275.     if (next < (width += left)) width = next;
  1276.     /* Draw data point lines. */
  1277.     for (i = left; i < width; i++)
  1278.         XDrawLine(dpy, win, w->load.fgGC, i, w->core.height,
  1279.           i, (int)(w->core.height-(w->load.valuedata[i] * w->core.height)
  1280.               /w->load.scale));
  1281.         }
  1282.  
  1283.     return(next);
  1284. }
  1285.  
  1286. #if apollo
  1287. /* ARGSUSED */
  1288. static void GetLoadPoint( w, closure, call_data )
  1289.      Widget    w;        /* unused */
  1290.      caddr_t    closure;    /* unused */
  1291.      caddr_t    call_data;    /* pointer to (double) return value */
  1292. {
  1293.      static Bool    firstTime = TRUE;
  1294.      static int     lastNullCpu;
  1295.      static int     lastClock;
  1296.      time_$clock_t  timeNow;
  1297.      double         temp;
  1298.      proc1_$info_t  info;
  1299.      status_$t      st;
  1300.  
  1301.      proc1_$get_info( (short) 2, info, st );
  1302.      time_$clock( timeNow );
  1303.  
  1304.      if (firstTime)
  1305.      {
  1306.          *(double *)call_data = 1.0;
  1307.          firstTime = FALSE;
  1308.      }
  1309.      else {
  1310.          temp = info.cpu_total.low32 - lastNullCpu;
  1311.          *(double *)call_data = 1.0 - temp / (timeNow.low32 - lastClock);
  1312.      }
  1313.  
  1314.      lastClock = timeNow.low32;
  1315.      lastNullCpu = info.cpu_total.low32;
  1316. }
  1317. #else
  1318. #ifdef LOADSTUB
  1319.  
  1320. /* ARGSUSED */
  1321. static void GetLoadPoint( w, closure, call_data )
  1322.      Widget    w;        /* unused */
  1323.      caddr_t    closure;    /* unused */
  1324.      caddr_t    call_data;    /* pointer to (double) return value */
  1325. {
  1326.     *(double *)call_data = 1.0;
  1327. }
  1328.  
  1329. #else /* LOADSTUB */
  1330.  
  1331. #ifndef KMEM_FILE
  1332. #define KMEM_FILE "/dev/kmem"
  1333. #endif
  1334.  
  1335. #ifndef KERNEL_FILE
  1336. #ifdef CRAY
  1337. #define KERNEL_FILE "/unicos"
  1338. #endif /* CRAY */
  1339. #ifdef hpux
  1340. #define KERNEL_FILE "/hp-ux"
  1341. #endif /* hpux */
  1342. #ifdef macII
  1343. #define KERNEL_FILE "/unix"
  1344. #endif /* macII */
  1345. #ifdef mips
  1346. # ifdef SYSTYPE_SYSV
  1347. # define KERNEL_FILE "/unix"
  1348. # else
  1349. # define KERNEL_FILE "/vmunix"
  1350. # endif /* SYSTYPE_SYSV */
  1351. #endif /* mips */
  1352. #ifdef sequent
  1353. #define KERNEL_FILE "/dynix"
  1354. #endif /* sequent */
  1355.  
  1356. /*
  1357.  * provide default for everyone else
  1358.  */
  1359. #ifndef KERNEL_FILE
  1360. #define KERNEL_FILE "/vmunix"
  1361. #endif /* KERNEL_FILE */
  1362. #endif /* KERNEL_FILE */
  1363.  
  1364.  
  1365. #ifndef KERNEL_LOAD_VARIABLE
  1366. #ifdef CRAY
  1367. #define KERNEL_LOAD_VARIABLE "avenrun"
  1368. #undef n_type
  1369. #define n_type n_value
  1370. #endif /* CRAY */
  1371. #ifdef hpux
  1372. #ifdef hp9000s800
  1373. #define KERNEL_LOAD_VARIABLE "avenrun"
  1374. #endif /* hp9000s800 */
  1375. #endif /* hpux */
  1376. #ifdef mips
  1377. # ifdef SYSTYPE_SYSV
  1378. # define KERNEL_LOAD_VARIABLE "avenrun"
  1379. # else
  1380. # define KERNEL_LOAD_VARIABLE "_avenrun"
  1381. # endif /* SYSTYPE_SYSV */
  1382. #endif /* mips */
  1383. #ifdef sequent
  1384. #define KERNEL_FILE "/dynix"
  1385. #endif /* sequent */
  1386. /*
  1387.  * provide default for everyone else
  1388.  */
  1389. #ifndef KERNEL_LOAD_VARIABLE
  1390. #define KERNEL_LOAD_VARIABLE "_avenrun"
  1391. #endif /* KERNEL_LOAD_VARIABLE */
  1392. #endif /* KERNEL_LOAD_VARIABLE */
  1393.  
  1394. #ifdef macII
  1395. static struct var v;
  1396. static struct nlist nl[2];
  1397. static struct lavnum vec[3];
  1398. #else /* not macII */
  1399. static struct nlist namelist[] = {        /* namelist for vmunix grubbing */
  1400. #define LOADAV 0
  1401.     {KERNEL_LOAD_VARIABLE},
  1402.     {0}
  1403. };
  1404. #endif /* macII */
  1405.  
  1406.  
  1407. /* ARGSUSED */
  1408. static void GetLoadPoint( w, closure, call_data )
  1409.      Widget    w;        /* unused */
  1410.      caddr_t    closure;    /* unused */
  1411.      caddr_t    call_data;    /* pointer to (double) return value */
  1412. {
  1413.       double *loadavg = (double *)call_data;
  1414.     static int init = 0;
  1415.     static kmem;
  1416.     static long loadavg_seek;
  1417. #ifdef macII
  1418.         extern nlist();
  1419.  
  1420.         if(!init)   {
  1421.             int i;
  1422.  
  1423.             strcpy(nl[0].n_name, "avenrun");
  1424.             nl[1].n_name[0] = '\0';
  1425.  
  1426.             kmem = open(KMEM_FILE, O_RDONLY);
  1427.             if (kmem < 0) {
  1428.             xload_error("cannot open", KMEM_FILE);
  1429.             }
  1430.  
  1431.             uvar(&v);
  1432.  
  1433.             if (nlist( KERNEL_FILE, nl) != 0) {
  1434.         xload_error("cannot get name list from", KERNEL_FILE);
  1435.             }
  1436.             for (i = 0; i < 2; i++) {
  1437.                 nl[i].n_value = (int)nl[i].n_value - v.v_kvoffset;
  1438.             }
  1439.             init = 1;
  1440.         }
  1441. #else /* not macII */
  1442.     extern void nlist();
  1443.     
  1444.     if(!init)   {
  1445.         nlist( KERNEL_FILE, namelist);
  1446.         if (namelist[LOADAV].n_type == 0){
  1447.         xload_error("cannot get name list from", KERNEL_FILE);
  1448.         exit(-1);
  1449.         }
  1450.         loadavg_seek = namelist[LOADAV].n_value;
  1451. # if defined(mips) && defined(SYSTYPE_SYSV)
  1452.         loadavg_seek &= 0x7fffffff;
  1453. # endif /* mips && SYSTYPE_SYSV */
  1454.         kmem = open(KMEM_FILE, O_RDONLY);
  1455.         if (kmem < 0) xload_error("cannot open", KMEM_FILE);
  1456.         init = 1;
  1457.     }
  1458.     
  1459.  
  1460.     (void) lseek(kmem, loadavg_seek, 0);
  1461. #endif /* macII */
  1462. #if defined(sun) || defined (UTEK) || defined(sequent)
  1463.     {
  1464.         long temp;
  1465.         (void) read(kmem, (char *)&temp, sizeof(long));
  1466.         *loadavg = (double)temp/FSCALE;
  1467.     }
  1468. #else /* else not sun */
  1469. # ifdef macII
  1470.         {
  1471.                 lseek(kmem, (long)nl[X_AVENRUN].n_value, 0);
  1472.                 read(kmem, vec, 3*sizeof(struct lavnum));
  1473.                 *loadavg = fxtod(0);
  1474.         }
  1475. # else /* else not macII */
  1476. #  ifdef mips
  1477.     {
  1478.         fix temp;
  1479.         (void) read(kmem, (char *)&temp, sizeof(fix));
  1480.         *loadavg = FIX_TO_DBL(temp);
  1481.     }
  1482. #  else /* not mips */
  1483.     (void) read(kmem, (char *)loadavg, sizeof(double));
  1484. #  endif /* mips */
  1485. # endif /* macII */
  1486. #endif /* sun */
  1487.     return;
  1488. }
  1489. #endif /* LOADSTUB */
  1490. #endif /* apollo */
  1491.  
  1492. static xload_error(str1, str2)
  1493. char *str1, *str2;
  1494. {
  1495.     (void) fprintf(stderr,"xload: %s %s\n", str1, str2);
  1496.     exit(-1);
  1497. }
  1498.  
  1499. /* ARGSUSED */
  1500. static Boolean SetValues (current, request, new)
  1501.     Widget current, request, new;
  1502. {
  1503.     LoadWidget old = (LoadWidget)current;
  1504.     LoadWidget w = (LoadWidget)new;
  1505.     if (w->load.update != old->load.update) {
  1506.     XtRemoveTimeOut (old->load.interval_id);
  1507.     w->load.interval_id =
  1508.         XtAddTimeOut(w->load.update*1000, draw_it, (caddr_t)w);
  1509.     }
  1510.  
  1511.     return( FALSE );
  1512. }
  1513. SHAR_EOF
  1514. if test -f 'X11/Load.h'
  1515. then
  1516.     echo shar: over-writing existing file "'X11/Load.h'"
  1517. fi
  1518. cat << \SHAR_EOF > 'X11/Load.h'
  1519. /*
  1520. * $XConsortium: Load.h,v 1.13 88/10/23 14:03:12 swick Exp $
  1521. */
  1522.  
  1523.  
  1524. /***********************************************************
  1525. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  1526. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  1527.  
  1528.                         All Rights Reserved
  1529.  
  1530. Permission to use, copy, modify, and distribute this software and its 
  1531. documentation for any purpose and without fee is hereby granted, 
  1532. provided that the above copyright notice appear in all copies and that
  1533. both that copyright notice and this permission notice appear in 
  1534. supporting documentation, and that the names of Digital or MIT not be
  1535. used in advertising or publicity pertaining to distribution of the
  1536. software without specific, written prior permission.  
  1537.  
  1538. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  1539. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  1540. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  1541. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  1542. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  1543. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  1544. SOFTWARE.
  1545.  
  1546. ******************************************************************/
  1547.  
  1548. #ifndef _XtLoad_h
  1549. #define _XtLoad_h
  1550.  
  1551. /***********************************************************************
  1552.  *
  1553.  * Load Widget
  1554.  *
  1555.  ***********************************************************************/
  1556.  
  1557. /* Parameters:
  1558.  
  1559.  Name             Class        RepType        Default Value
  1560.  ----             -----        -------        -------------
  1561.  background         Background        Pixel        White
  1562.  border             BorderColor    Pixel        Black
  1563.  borderWidth         BorderWidth    Dimension    1
  1564.  destroyCallback     Callback        Pointer        NULL
  1565.  font             Font        XFontStruct*    XtDefaultFont
  1566.  foreground         Foreground        Pixel        Black
  1567.  getLoadProc         Callback        Callback    (internal)
  1568.  height             Height        Dimension    120
  1569.  highlight         Foreground        Pixel        Black
  1570.  label             Label        String        (empty string)
  1571.  mappedWhenManaged   MappedWhenManaged    Boolean        True
  1572.  minScale         Scale        int        1
  1573.  reverseVideo         ReverseVideo    Boolean        False
  1574.  scale             Scale        int        1
  1575.  update             Interval        int        5 (seconds)
  1576.  width             Width        Dimension    120
  1577.  x             Position        Position    0
  1578.  y             Position        Position    0
  1579.  
  1580. */
  1581.  
  1582.  
  1583. #define XtNupdate        "update"
  1584. #define XtNscale        "scale"
  1585. #define XtNvmunix        "vmunix"
  1586. #define XtNminScale        "minScale"
  1587. #define XtNgetLoadProc        "getLoadProc"
  1588. #define XtNhighlight        "highlight"
  1589.  
  1590. #define XtCScale        "Scale"
  1591.  
  1592. typedef struct _LoadRec *LoadWidget;  /* completely defined in LoadPrivate.h */
  1593. typedef struct _LoadClassRec *LoadWidgetClass;    /* completely defined
  1594. in LoadPrivate.h */
  1595.  
  1596. extern WidgetClass loadWidgetClass;
  1597.  
  1598. #endif _XtLoad_h
  1599. /* DON'T ADD STUFF AFTER THIS #endif */
  1600. SHAR_EOF
  1601. if test -f 'X11/LoadP.h'
  1602. then
  1603.     echo shar: over-writing existing file "'X11/LoadP.h'"
  1604. fi
  1605. cat << \SHAR_EOF > 'X11/LoadP.h'
  1606. /*
  1607. * $XConsortium: LoadP.h,v 1.11 88/09/06 16:41:56 jim Exp $
  1608. */
  1609.  
  1610.  
  1611. /***********************************************************
  1612. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  1613. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  1614.  
  1615.                         All Rights Reserved
  1616.  
  1617. Permission to use, copy, modify, and distribute this software and its 
  1618. documentation for any purpose and without fee is hereby granted, 
  1619. provided that the above copyright notice appear in all copies and that
  1620. both that copyright notice and this permission notice appear in 
  1621. supporting documentation, and that the names of Digital or MIT not be
  1622. used in advertising or publicity pertaining to distribution of the
  1623. software without specific, written prior permission.  
  1624.  
  1625. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  1626. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  1627. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  1628. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  1629. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  1630. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  1631. SOFTWARE.
  1632.  
  1633. ******************************************************************/
  1634.  
  1635. #ifndef _LoadP_h
  1636. #define _LoadP_h
  1637.  
  1638. #include <X11/Load.h>
  1639. #include <X11/CoreP.h>
  1640.  
  1641. #define SEG_BUFF_SIZE        128
  1642.  
  1643. /* New fields for the load widget instance record */
  1644. typedef struct {
  1645.      Pixel    fgpixel;    /* color index for graph */
  1646.      Pixel    hipixel;    /* color index for text */
  1647.      XFontStruct    *font;    /* font for text */
  1648.      GC    fgGC;        /* graphics context for fgpixel */
  1649.      GC    hiGC;        /* graphics context for hipixel */
  1650. /* start of graph stuff */
  1651.      int    update;        /* update frequence */
  1652.      int    scale;        /* scale factor */
  1653.      int     min_scale;    /* smallest scale factor */
  1654.      int     interval;    /* data point interval */
  1655.      Boolean reverse_video;        /* display in reverse video */
  1656.      char    *text;        /* label */
  1657.      double max_value;    /* Max Value in window */
  1658.      double valuedata[2048];/* record of data points */
  1659.      XtIntervalId interval_id;
  1660.      XtCallbackList get_load; /* proc to call to fetch load pt */
  1661.    } LoadPart;
  1662.  
  1663. /* Full instance record declaration */
  1664. typedef struct _LoadRec {
  1665.    CorePart core;
  1666.    LoadPart load;
  1667.    } LoadRec;
  1668.  
  1669. /* New fields for the Load widget class record */
  1670. typedef struct {int dummy;} LoadClassPart;
  1671.  
  1672. /* Full class record declaration. */
  1673. typedef struct _LoadClassRec {
  1674.    CoreClassPart core_class;
  1675.    LoadClassPart load_class;
  1676.    } LoadClassRec;
  1677.  
  1678. /* Class pointer. */
  1679. extern LoadClassRec loadClassRec;
  1680.  
  1681. #endif _LoadP_h
  1682. SHAR_EOF
  1683. #    End of shell archive
  1684. exit 0
  1685.  
  1686. dan
  1687. -----------------------------------------------------------
  1688.             O'Reilly && Associates
  1689.         argv@sun.com / argv@ora.com
  1690.        632 Petaluma Ave, Sebastopol, CA 95472 
  1691.      800-338-NUTS, in CA: 800-533-NUTS, FAX 707-829-0104
  1692.     Opinions expressed reflect those of the author only.
  1693.